package com.skt.service.impl;

import com.skt.config.CacheConstants;
import com.skt.context.RequestContext;
import com.skt.domain.DTO.request.AddToCartRequest;
import com.skt.domain.PO.CartItem;
import com.skt.domain.PO.Costume;
import com.skt.domain.PO.ShoppingCart;
import com.skt.domain.VO.CartVO;
import com.skt.exception.*;
import com.skt.mapper.CartItemMapper;
import com.skt.mapper.CostumeMapper;
import com.skt.mapper.ShoppingCartMapper;
import com.skt.security.LoginUser;
import com.skt.service.CartService;
import com.skt.utils.LogUtil;
import com.skt.utils.RedisUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 购物车服务实现类
 * 负责购物车的创建、获取、商品管理等核心业务逻辑
 * 采用多级缓存策略：Redis缓存 -> 数据库查询，提升性能
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class CartServiceImpl implements CartService {

    // ========== 依赖注入 ==========
    private final RedisUtil redisUtil;                    // Redis工具类，用于缓存操作
    private final ShoppingCartMapper shoppingCartMapper;  // 购物车数据访问接口
    private final CartItemMapper cartItemMapper;          // 购物车项数据访问接口
    private final CostumeMapper costumeMapper;            // 服装商品数据访问接口

    /**
     * 创建或获取购物车 - 主业务方法
     * 实现购物车懒加载模式：用户首次访问时自动创建购物车
     * 采用读事务优化查询性能
     *
     * @return CartVO 购物车视图对象，包含完整的购物车信息
     * @throws CartException 购物车操作异常
     */
    @Override
    @Transactional()
    public CartVO createOrGetCart() {

        // 1.1 获取用户ID
        Long currentUserId = getCurrentUserId();

        try {
            LogUtil.startTimer("CREATE_OR_GET_CART");

            LogUtil.info("CART", "CREATE_OR_GET", "开始获取购物车，用户ID: %d",
                    currentUserId);

            // 1.2 获取请求上下文
            RequestContext context = buildRequestContext(currentUserId);
            // 2. 购物车存在性智能检查（采用多级缓存策略）
            LogUtil.debug("CART", "CHECK_EXISTS", "检查购物车是否存在，用户ID: %d",
                    currentUserId);
            ShoppingCart cart = checkCartExists(currentUserId);

            // 3. 分支处理：根据购物车是否存在采取不同策略
            if (cart == null) {
                log.info("购物车不存在，创建新购物车: userId={}", currentUserId);
                return handleCartNotExists(currentUserId, context);
            } else {
                log.info("购物车存在，验证并处理: userId={}, cartId={}", currentUserId, cart.getId());
                return handleCartExists(cart, context);
            }
        } catch (Exception e) {
            log.error("获取购物车异常: userId={}, error={}", currentUserId, e.getMessage());
            throw CartException.of(CartErrorCode.GET_CART_FAILED);
        }
    }

    @Override
    @Transactional()
    public CartVO addToCart(AddToCartRequest addRequest) {

        // 1. 用户认证
        Long currentUserId = getCurrentUserId();

        // 2. 参数校验
        addToCartValidateParam(addRequest);

        LogUtil.info("CART", "VALIDATE", "用户ID: {}, 请求: costumeID={}, quantity={}",
                currentUserId, addRequest.getCostumeId(), addRequest.getQuantity());

        // 3. 获取购物车
        ShoppingCart shoppingCart = getShoppingCart(currentUserId);
        if (shoppingCart == null) {
            throw CartException.of(CartErrorCode.CART_NOT_FOUND, "购物车不存在，请先创建购物车");
        }

        // 4. 商品验证
        Costume costume = checkCostumeExists(addRequest);

        log.info("查询到的商品: id={}, stock={}, status={}",
                costume.getId(), costume.getStock(), costume.getStatus());

        // 5. 分布式锁
        String stockKey = CacheConstants.COSTUME_STOCK_KEY_PREFIX + currentUserId;
        String requestId = UUID.randomUUID().toString();
        boolean acquiredKey;

        try {
            acquiredKey = redisUtil.tryLock(stockKey, requestId, 30, TimeUnit.SECONDS);
            if (!acquiredKey) {
                throw CartException.of(CartErrorCode.CART_CONCURRENT_UPDATE);
            }

            // 6. 查找或创建购物车项
            CartItem cartItem = findCartItemByCartIdAndCostumeId(shoppingCart.getId(), costume.getId());

            if (cartItem == null) {
                // 创建新地购物车项
                cartItem = createNewCartItem(shoppingCart.getId(), costume, addRequest);
                log.info("创建新购物车项: costumeId={}, quantity={}", costume.getId(), addRequest.getQuantity());
            } else {
                // 更新现有购物车项数量
                costumeAdd(cartItem, addRequest);
                log.info("更新购物车项数量: 原数量={}, 新增={}, 新数量={}",
                        cartItem.getQuantity() - addRequest.getQuantity(),
                        addRequest.getQuantity(), cartItem.getQuantity());
            }

            // 7. 库存验证
            if (cartItem.getQuantity() > costume.getStock()) {
                throw CartException.of(CartErrorCode.EXCEED_MAX_QUANTITY);
            }

            // 8. 保存购物车项
            cartStore(cartItem);

            // 9. 更新购物车统计信息
            updateCartStatistics(shoppingCart);

            return getCartVO(shoppingCart);

        } catch (CartException e) {
            throw e;
        } catch (Exception e) {
            log.error("加入购物车失败 error={}", e.getMessage(), e);
            throw CartException.of(CartErrorCode.ADD_TO_CART_FAILED);
        } finally {
            redisUtil.releaseLock(stockKey, requestId);
        }
    }

    /**
     * 删除购物车中的商品项
     * @param itemId 要删除的购物车项ID
     */
    @Override
    @Transactional
    public void removeFromCartItem(Long itemId) {
        // 1. 用户身份认证
        Long currentUserId = getCurrentUserId();

        // 2. 参数校验
        validateCartRemove(itemId);

        // 3. 获取购物车
        ShoppingCart cart = getShoppingCart(currentUserId);
        if (cart == null) {
            throw CartException.of(CartErrorCode.CART_NOT_FOUND);
        }

        // 4. 验证购物车归属
        validateCartOwnership(cart, currentUserId);

        // 5. 删除购物车条目
        deleteCartItem(cart, itemId, currentUserId);
    }

    /**
     * 删除购物车中的单个商品项
     * @param cart 购物车
     * @param itemId 购物车项ID
     * @param userId 用户ID
     */
    private void deleteCartItem(ShoppingCart cart, Long itemId, Long userId) {
        // 1. 验证购物车项是否存在且属于该购物车
        validateAndGetCartItem(itemId, cart.getId());

        // 2. 从数据库中删除购物车项
        deleteCartItemInDatabase(itemId);

        // 3. 从缓存中删除购物车项
        deleteCartItemInRedis(itemId);

        // 4. 更新购物车统计信息
        updateCartStatisticsAfterDelete(cart);

        log.info("删除购物车项成功: userId={}, cartId={}, itemId={}", userId, cart.getId(), itemId);
    }

    /**
     * 验证购物车项是否存在且属于指定购物车
     */
    private CartItem validateAndGetCartItem(Long itemId, Long cartId) {
        try {
            CartItem cartItem = cartItemMapper.selectById(itemId);
            if (cartItem == null) {
                throw CartException.of(CartErrorCode.CART_ITEM_NOT_FOUND);
            }
            if (!cartItem.getCartId().equals(cartId)) {
                throw CartException.of(CartErrorCode.CART_ACCESS_DENIED);
            }
            return cartItem;
        } catch (Exception e) {
            log.error("验证购物车项失败: itemId={}, cartId={}, error={}", itemId, cartId, e.getMessage());
            throw CartException.of(CartErrorCode.CART_OPERATION_FAILED);
        }
    }

    /**
     * 从数据库中删除购物车项
     */
    private void deleteCartItemInDatabase(Long itemId) {
        try {
            int affectedRows = cartItemMapper.deleteById(itemId);
            if (affectedRows == 0) {
                throw CartException.of(CartErrorCode.CART_ITEM_NOT_FOUND);
            }
            log.info("从数据库中删除购物车项成功: itemId={}", itemId);
        } catch (CartException e) {
            throw e;
        } catch (Exception e) {
            log.error("数据库删除购物车项失败: itemId={}, error={}", itemId, e.getMessage());
            throw CartException.of(CartErrorCode.CART_OPERATION_FAILED);
        }
    }

    /**
     * 从缓存中删除购物车项
     */
    private void deleteCartItemInRedis(Long itemId) {
        try {
            String cartItemKey = CacheConstants.CART_ITEM_KEY_PREFIX + itemId;
            redisUtil.delete(cartItemKey);
            log.info("缓存删除购物车项成功: itemId={}", itemId);
        } catch (Exception e) {
            log.warn("缓存删除购物车项失败: itemId={}, error={}", itemId, e.getMessage());
            // 缓存删除失败不阻塞主流程，只记录警告
        }
    }

    /**
     * 删除购物车项后更新购物车统计信息
     */
    private void updateCartStatisticsAfterDelete(ShoppingCart cart) {
        try {
            // 重新计算购物车总数量和总金额
            List<CartItem> items = cartItemMapper.selectByCartId(cart.getId());

            int totalItems = items.stream().mapToInt(CartItem::getQuantity).sum();
            BigDecimal totalAmount = items.stream()
                    .map(item -> item.getDailyPrice().multiply(BigDecimal.valueOf(item.getQuantity())))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            cart.setTotalItems(totalItems);
            cart.setTotalAmount(totalAmount);
            cart.setUpdatedAt(LocalDateTime.now());

            // 更新数据库
            shoppingCartMapper.updateById(cart);
            // 更新缓存
            cacheCartToRedis(cart);

            log.info("删除后更新购物车统计信息成功: cartId={}, totalItems={}, totalAmount={}",
                    cart.getId(), totalItems, totalAmount);

        } catch (Exception e) {
            log.error("删除后更新购物车统计信息失败: cartId={}, error={}", cart.getId(), e.getMessage());
            throw CartException.of(CartErrorCode.CART_OPERATION_FAILED);
        }
    }

    /**
     * 验证购物车归属权
     */
    private void validateCartOwnership(ShoppingCart cart, Long userId) {
        if (!cart.getUserId().equals(userId)) {
            log.warn("购物车归属验证失败: cartUserId={}, currentUserId={}", cart.getUserId(), userId);
            throw CartException.of(CartErrorCode.CART_ACCESS_DENIED);
        }
    }

    /**
     * 校验移除购物车参数
     */
    private void validateCartRemove(Long itemId) {
        if (itemId == null || itemId <= 0) {
            throw ValidationException.of(ValidationErrorCode.PARAM_INVALID);
        }
    }

    /**
     * 获取购物车
     */
    private ShoppingCart getShoppingCart(Long userId) {
        try {
            // 先尝试从Redis获取
            ShoppingCart cart = getCartFromRedis(userId);
            if (cart != null) {
                log.info("Redis缓存命中购物车: userId={}, ShoppingCartId={}", userId, cart.getId());
                return cart;
            }

            // Redis未命中，查询数据库
            cart = shoppingCartMapper.selectByUserId(userId);
            if (cart != null) {
                // 查询成功，更新缓存
                cacheCartToRedis(cart);
                log.info("数据库查询到购物车: userId={}, cartId={}", userId, cart.getId());
            } else {
                log.info("购物车不存在: userId={}", userId);
            }

            return cart;
        } catch (Exception e) {
            log.error("查询购物车失败: userId={}, error={}", userId, e.getMessage());
            return null;
        }
    }

    /**
     * 根据购物车ID和商品ID查找购物车项
     */
    private CartItem findCartItemByCartIdAndCostumeId(Long cartId, Long costumeId) {
        try {
            CartItem cartItem = cartItemMapper.selectByCartIdAndCostumeId(cartId, costumeId);
            log.info("查询购物车项结果: cartId={}, costumeId={}, result={}", cartId, costumeId, cartItem);
            return cartItem;
        } catch (Exception e) {
            log.warn("查询购物车项失败: cartId={}, costumeId={}, error={}",
                    cartId, costumeId, e.getMessage());
            return null;
        }
    }

    /**
     * 创建新的购物车项
     */
    private CartItem createNewCartItem(Long cartId, Costume costume, AddToCartRequest addRequest) {
        CartItem cartItem = new CartItem();
        cartItem.setCartId(cartId);
        cartItem.setCostumeId(costume.getId());
        cartItem.setMerchantId(costume.getMerchantId());
        cartItem.setQuantity(addRequest.getQuantity());
        cartItem.setDailyPrice(costume.getRentalPrice());
        cartItem.setSelected(1); // 默认选中
        cartItem.setRentalDays(1); // 默认租赁天数
        cartItem.setCreatedAt(LocalDateTime.now());
        cartItem.setUpdatedAt(LocalDateTime.now());
        return cartItem;
    }

    /**
     * 更新购物车统计信息
     */
    private void updateCartStatistics(ShoppingCart cart) {
        try {
            // 重新计算购物车总数量和总金额
            List<CartItem> items = cartItemMapper.selectByCartId(cart.getId());

            int totalItems = items.stream().mapToInt(CartItem::getQuantity).sum();
            BigDecimal totalAmount = items.stream()
                    .map(item -> item.getDailyPrice().multiply(BigDecimal.valueOf(item.getQuantity())))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            cart.setTotalItems(totalItems);
            cart.setTotalAmount(totalAmount);
            cart.setUpdatedAt(LocalDateTime.now());

            // 更新数据库
            shoppingCartMapper.updateById(cart);
            // 更新缓存
            cacheCartToRedis(cart);

            log.info("更新购物车统计信息成功: cartId={}, totalItems={}, totalAmount={}",
                    cart.getId(), totalItems, totalAmount);

        } catch (Exception e) {
            log.warn("更新购物车统计信息失败: cartId={}, error={}", cart.getId(), e.getMessage());
        }
    }

    /**
     * 获取购物车VO对象
     */
    private CartVO getCartVO(ShoppingCart cart) {
        try {
            return handleCartExists(cart, buildRequestContext(cart.getUserId()));
        } catch (Exception e) {
            log.error("获取购物车VO失败，返回空购物车: cartId={}, error={}", cart.getId(), e.getMessage());
            return assembleEmptyCartVO(cart);
        }
    }

    /**
     * 保存购物车项
     */
    private void cartStore(CartItem cartItem) {
        // 1. redis缓存
        cartStoreInRedis(cartItem);

        // 2. 数据库更新
        cartStoreInDatabase(cartItem);
    }

    /**
     * 保存到数据库
     */
    private void cartStoreInDatabase(CartItem cartItem) {
        try {
            if (cartItem.getId() == null) {
                cartItemMapper.insert(cartItem);
                log.info("数据库插入成功 cartItemId={}", cartItem.getId());
            } else {
                cartItemMapper.updateById(cartItem);
                log.info("数据库更新成功 cartItemId={}", cartItem.getId());
            }
        } catch (Exception e) {
            log.error("数据库操作失败 cartItem={}, error={}", cartItem, e.getMessage());
            throw CartException.of(CartErrorCode.CART_OPERATION_FAILED, "保存购物车项失败");
        }
    }

    /**
     * 保存到Redis
     */
    private void cartStoreInRedis(CartItem cartItem) {
        try {
            String cartKey = CacheConstants.CART_ITEM_KEY_PREFIX + cartItem.getId();
            redisUtil.set(cartKey, cartItem, 30, TimeUnit.DAYS);
            log.info("缓存成功 cartItemId={}", cartItem.getId());
        } catch (Exception e) {
            log.warn("缓存失败 cartItemId={}, error={}", cartItem.getId(), e.getMessage());
        }
    }


    /**
     * 更新购物车项数量
     */
    private void costumeAdd(CartItem cartItem, AddToCartRequest addRequest) {
        int sum = cartItem.getQuantity() + addRequest.getQuantity();
        cartItem.setQuantity(sum);
        cartItem.setUpdatedAt(LocalDateTime.now());
    }

    /**
     * 验证商品是否存在
     */
    private Costume checkCostumeExists(AddToCartRequest addRequest) {
        try {
            // 1. 在缓存中查询
            Costume costume = getCostumeFromRedis(addRequest);
            if (costume != null) {
                return costume;
            }
            log.info("缓存未查询到数据，降级到数据库查询");
            // 2. 在数据库中查询
            costume = getCostumeFromDatabase(addRequest);
            if (costume != null) {
                return costume;
            }
            log.warn("数据库中未查询到数据");
        } catch (Exception e) {
            log.error("查询商品失败 error={}", e.getMessage());
        }
        throw CartException.of(CartErrorCode.PRODUCT_NOT_FOUND);
    }

    /**
     * 从数据库查询商品
     */
    private Costume getCostumeFromDatabase(AddToCartRequest addRequest) {
        Costume costume = costumeMapper.selectById(addRequest.getCostumeId());
        if (costume != null) {
            if (validateCostume(addRequest, costume)) {
                // 回写缓存
                String costumeKey = CacheConstants.COSTUME_INFO_KEY_PREFIX + addRequest.getCostumeId();
                redisUtil.set(costumeKey, costume, 30, TimeUnit.DAYS);
                return costume;
            } else {
                throw CartException.of(CartErrorCode.INVALID_PRODUCT_INFO);
            }
        }
        throw CartException.of(CartErrorCode.PRODUCT_NOT_FOUND);
    }

    /**
     * 从Redis查询商品
     */
    private Costume getCostumeFromRedis(AddToCartRequest addRequest) {
        String costumeKey = CacheConstants.COSTUME_INFO_KEY_PREFIX + addRequest.getCostumeId();
        Object cached = redisUtil.get(costumeKey);

        if (cached instanceof Costume) {
            Costume costume = (Costume) cached;
            if (validateCostume(addRequest, costume)) {
                return costume;
            }
            log.info("缓存数据失效");
        } else {
            log.info("缓存未命中 costumeId={}", addRequest.getCostumeId());
            return null;
        }
        log.warn("缓存查询异常");
        return null;
    }

    /**
     * 验证商品信息
     */
    private boolean validateCostume(AddToCartRequest addRequest, Costume costume) {
        if (costume.getStatus() != 1) {
            log.warn("商品状态无效: costumeId={}, status={}", costume.getId(), costume.getStatus());
            return false;
        }
        if (addRequest.getQuantity() > costume.getStock()) {
            log.warn("库存不足: costumeId={}, requestQuantity={}, stock={}",
                    costume.getId(), addRequest.getQuantity(), costume.getStock());
            return false;
        }
        return true;
    }

    /**
     * 参数校验
     */
    private void addToCartValidateParam(AddToCartRequest addRequest) {
        if (addRequest == null) {
            throw ValidationException.of(ValidationErrorCode.FIELD_REQUIRED);
        }
        if (addRequest.getCostumeId() == null || addRequest.getCostumeId() <= 0) {
            throw CartException.of(CartErrorCode.INVALID_PRODUCT_INFO);
        }
        if (addRequest.getQuantity() == null ||
                addRequest.getQuantity() < 1 || addRequest.getQuantity() > 999) {
            throw CartException.of(CartErrorCode.INVALID_QUANTITY);
        }
    }

    // ========== 购物车存在性检查 ==========

    /**
     * 购物车存在性智能检查方法
     * 采用多级缓存策略：Redis缓存优先 -> 数据库查询兜底
     * 图片显示第75行存在变量初始值设定项冗余警告
     *
     * @param currentUserId 当前用户ID
     * @return ShoppingCart 购物车实体，不存在返回null
     */
    private ShoppingCart checkCartExists(Long currentUserId) {

        // 2.1 分布式缓存查询：优先从Redis获取，提升响应速度
        ShoppingCart cart = getCartFromRedis(currentUserId);
        if (cart != null) {
            log.info("Redis缓存命中购物车: userId={}, cartId={}", currentUserId, cart.getId());
            return cart;
        }

        log.info("缓存未命中，降级到数据库查询: userId={}", currentUserId);

        // 2.2 数据库持久化检查：缓存未命中时查询数据库
        return getCartFromDatabase(currentUserId);
    }

    /**
     * 从Redis缓存获取购物车数据
     * 处理缓存穿透、缓存击穿等异常情况
     *
     * @param currentUserId 当前用户ID
     * @return ShoppingCart 缓存中的购物车数据，不存在返回null
     */
    private ShoppingCart getCartFromRedis(Long currentUserId) {
        try {
            String cartKey = CacheConstants.CART_KEY_PREFIX + currentUserId;
            Object cached = redisUtil.get(cartKey);
            if (cached instanceof ShoppingCart) {
                ShoppingCart cart = (ShoppingCart) cached;
                // 缓存有效性验证：检查数据完整性和过期状态
                if (validateCachedCart(cart)) {
                    return cart;
                } else {
                    log.warn("Redis缓存数据无效，重新查询: userId={}", currentUserId);
                    redisUtil.delete(cartKey); // 删除无效缓存，防止缓存污染
                    return null;
                }
            }
            return null;
        } catch (Exception e) {
            log.warn("Redis查询异常，降级到数据库: userId={}, error={}", currentUserId, e.getMessage());
            return null;
        }
    }

    /**
     * 验证缓存中购物车数据的有效性
     * 检查关键字段是否存在、数据是否过期
     *
     * @param cart 购物车实体
     * @return boolean 数据是否有效
     */
    private boolean validateCachedCart(ShoppingCart cart) {
        return cart != null &&
                cart.getId() != null &&
                cart.getUserId() != null &&
                cart.getUpdatedAt() != null &&
                !isCartExpired(cart);
    }

    /**
     * 检查购物车是否过期
     * 默认30天未更新的购物车视为过期
     *
     * @param cart 购物车实体
     * @return boolean 是否过期
     */
    private boolean isCartExpired(ShoppingCart cart) {
        return cart.getUpdatedAt().isBefore(LocalDateTime.now().minusDays(30));
    }

    /**
     * 从数据库获取购物车数据
     * 查询成功后回写到缓存，保证下次快速访问
     * 图片显示第126行存在不兼容的类型错误
     *
     * @param userId 用户ID
     * @return ShoppingCart 数据库中的购物车数据
     */
    private ShoppingCart getCartFromDatabase(Long userId) {
        try {
            ShoppingCart cart =  shoppingCartMapper.selectByUserId(userId);
            if (cart != null) {
                // 数据库记录验证：检查业务状态和数据完整性
                if (validateDatabaseCart(cart)) {
                    log.info("数据库查询到有效购物车: userId={}, cartId={}", userId, cart.getId());
                    // 查询成功，回写到缓存，提升后续访问性能
                    cacheCartToRedis(cart);
                    return cart;
                } else {
                    log.warn("数据库购物车数据无效: userId={}, cartId={}", userId, cart.getId());
                    return null;
                }
            } else {
                log.info("数据库中不存在购物车: userId={}", userId);
                return null;
            }
        } catch (Exception e) {
            log.warn("数据库查询异常，返回null: userId={}, error={}", e.getMessage());
            return null;
        }
    }

    /**
     * 验证数据库购物车数据的业务有效性
     * 检查状态字段、删除标记等业务规则
     *
     * @param cart 购物车实体
     * @return boolean 数据是否业务有效
     */
    private boolean validateDatabaseCart(ShoppingCart cart) {
        return cart.getStatus() == 1 && // 状态有效：1-正常状态
                cart.getDeletedAt() == null; // 未删除：删除时间为空
    }

    // ========== 分支处理：购物车不存在 ==========

    /**
     * 处理购物车不存在的情况
     * 创建新购物车并初始化基础数据
     *
     * @param userId 用户ID
     * @param context 请求上下文
     * @return CartVO 新创建的购物车视图对象
     */
    private CartVO handleCartNotExists(Long userId, RequestContext context) {
        // 4.1 基础数据初始化：创建购物车实体对象
        ShoppingCart newCart = createNewCart(userId);

        // 4.3 数据持久化存储：保存到数据库
        persistNewCart(newCart);

        // 5.1 缓存层优化：写入Redis缓存
        cacheCartToRedis(newCart);

        // 6.1 响应数据组装：转换为前端需要的VO对象
        CartVO emptyCart = assembleEmptyCartVO(newCart);

        // 7.1 监控统计：记录创建操作指标
        recordCartCreationMetrics(context, newCart);

        log.info("创建新购物车成功: userId={}, cartId={}", userId, newCart.getId());
        return emptyCart;
    }

    /**
     * 创建新购物车实体
     * 初始化所有必要字段，设置默认值
     *
     * @param userId 用户ID
     * @return ShoppingCart 新创建的购物车实体
     */
    private ShoppingCart createNewCart(Long userId) {
        ShoppingCart cart = new ShoppingCart();
        cart.setUserId(userId);
        cart.setTotalItems(0);                    // 初始商品数量为0
        cart.setTotalAmount(BigDecimal.ZERO);     // 初始总金额为0
        cart.setCreatedAt(LocalDateTime.now());   // 创建时间
        cart.setUpdatedAt(LocalDateTime.now());   // 更新时间
        cart.setStatus(1);                        // 状态：1-有效

        return cart;
    }

    /**
     * 持久化新购物车到数据库
     * 使用事务保证数据一致性
     *
     * @param cart 购物车实体
     */
    private void persistNewCart(ShoppingCart cart) {
        try {
            shoppingCartMapper.insert(cart);
            log.info("购物车持久化成功: cartId={}", cart.getId());
        } catch (Exception e) {
            log.error("购物车持久化失败: userId={}, error={}", cart.getUserId(), e.getMessage());
            throw CartException.of(CartErrorCode.CART_OPERATION_FAILED, "创建购物车失败");
        }
    }

    /**
     * 组装空购物车响应对象
     * 包含购物车基础信息，商品列表为空
     *
     * @param cart 购物车实体
     * @return CartVO 购物车视图对象
     */
    private CartVO assembleEmptyCartVO(ShoppingCart cart) {
        CartVO cartVO = new CartVO();
        cartVO.setCartId(cart.getId());
        cartVO.setUserId(cart.getUserId());
        cartVO.setTotalItems(0); // 商品数量
        cartVO.setTotalAmount(BigDecimal.ZERO); // 商品金额
        cartVO.setItems(new ArrayList<>());       // 空商品列表
        cartVO.setCreatedAt(cart.getCreatedAt());
        cartVO.setUpdatedAt(cart.getUpdatedAt());
        return cartVO;
    }

    // ========== 分支处理：购物车存在 ==========

    /**
     * 处理已存在购物车的情况
     * 加载商品数据、计算价格、组装响应
     *
     * @param cart 购物车实体
     * @param context 请求上下文
     * @return CartVO 完整的购物车视图对象
     */
    private CartVO handleCartExists(ShoppingCart cart, RequestContext context) {
        // 3.1 验证购物车状态：检查业务规则有效性
        validateCartStatus(cart);

        // 3.1 商品数据批量加载：获取购物车中所有商品项
        List<CartItem> cartItems = loadCartItems(cart.getId());

        // 3.2 实时信息同步更新 + 3.3 价格重计算
        List<CartVO.CartItemVO> enrichedItems = processCartItems(cartItems);

        // 3.3 总计金额更新：重新计算购物车统计信息
        updateCartStatistics(cart, enrichedItems);

        // 6.1 响应数据统一组装：转换为前端需要的格式
        CartVO cartVO = assembleCartResponse(cart, enrichedItems);

        // 7.1 监控统计：记录访问操作指标
        recordCartAccessMetrics(context, cartVO);

        return cartVO;
    }

    /**
     * 验证购物车业务状态
     * 检查是否可正常使用，防止操作无效购物车
     *
     * @param cart 购物车实体
     * @throws CartException 购物车状态异常
     */
    private void validateCartStatus(ShoppingCart cart) {
        if (cart.getStatus() != 1) {
            throw CartException.of(CartErrorCode.CART_ITEM_INVALID, "购物车状态异常");
        }
        if (cart.getDeletedAt() != null) {
            throw CartException.of(CartErrorCode.CART_NOT_FOUND, "购物车已被删除");
        }
    }

    /**
     * 加载购物车项列表
     * 从数据库查询购物车中的所有商品项
     *
     * @param cartId 购物车ID
     * @return List<CartItem> 购物车项列表
     */
    private List<CartItem> loadCartItems(Long cartId) {
        try {
            List<CartItem> items = cartItemMapper.selectByCartId(cartId);
            log.info("加载购物车项成功: cartId={}, itemCount={}", cartId, items.size());
            return items;
        } catch (Exception e) {
            log.error("加载购物车项失败: cartId={}, error={}", cartId, e.getMessage());
            throw CartException.of(CartErrorCode.GET_CART_FAILED);
        }
    }

    /**
     * 处理购物车项数据
     * 批量获取商品信息、同步实时数据、重新计算价格
     *
     * @param cartItems 购物车项列表
     * @return List<CartItemVO> 处理后的购物车项视图对象列表
     */
    private List<CartVO.CartItemVO> processCartItems(List<CartItem> cartItems) {
        if (cartItems.isEmpty()) {
            return new ArrayList<>();
        }

        // 3.1 并行查询优化：提取所有商品ID进行批量查询
        List<Long> costumeIds = cartItems.stream()
                .map(CartItem::getCostumeId)
                .distinct()
                .collect(Collectors.toList());

        // 批量获取商品信息：减少数据库查询次数
        Map<Long, Object> costumeInfoMap = batchGetCostumeInfo(costumeIds);

        // 3.2 实时信息同步更新 + 3.3 价格重算
        return cartItems.parallelStream()                    // 并行处理提升性能
                .map(item -> processSingleCartItem(item, costumeInfoMap))
                .filter(Objects::nonNull)                   // 过滤无效商品项
                .collect(Collectors.toList());
    }

    /**
     * 批量获取商品信息
     * 使用并行查询优化性能，合并商品详情和库存信息
     * 图片显示第278、281行存在无法解析方法错误
     *
     * @param costumeIds 商品ID列表
     * @return Map<Long, Object> 商品信息映射表
     */
    private Map<Long, Object> batchGetCostumeInfo(List<Long> costumeIds) {
        try {
            if (costumeIds == null || costumeIds.isEmpty()) {
                return new HashMap<>();
            }

            // 直接查询数据库获取商品信息
            List<Costume> costumes = costumeMapper.selectBatchIds(costumeIds);

            // 转换为Map格式
            Map<Long, Object> result = new HashMap<>();
            for (Costume costume : costumes) {
                if (costume != null) {
                    // 构建商品信息对象
                    Map<String, Object> costumeInfo = new HashMap<>();
                    costumeInfo.put("id", costume.getId());
                    costumeInfo.put("name", costume.getName());
                    costumeInfo.put("dailyPrice", costume.getRentalPrice());
                    costumeInfo.put("stock", costume.getStock());
                    costumeInfo.put("status", costume.getStatus());
                    costumeInfo.put("imageUrl", costume.getImageUrl());

                    result.put(costume.getId(), costumeInfo);
                }
            }

            log.info("批量获取商品信息成功: costumeIds={}, resultSize={}", costumeIds.size(), result.size());
            return result;

        } catch (Exception e) {
            log.warn("批量获取商品信息失败: costumeIds={}, error={}", costumeIds, e.getMessage());
            return new HashMap<>();
        }
    }

    /**
     * 处理单个购物车项
     * 转换VO对象、检测价格变动、同步库存状态、计算小计
     *
     * @param item 购物车项实体
     * @param costumeInfoMap 商品信息映射表
     * @return CartItemVO 处理后的购物车项视图对象
     */
    private CartVO.CartItemVO processSingleCartItem(CartItem item, Map<Long, Object> costumeInfoMap) {
        try {
            CartVO.CartItemVO itemVO = convertToCartItemVO(item);

            // 3.2 价格变动检测：比较历史价格和当前价格
            detectPriceChanges(itemVO, costumeInfoMap);

            // 3.2 库存状态同步：检查商品库存是否充足
            syncStockStatus(itemVO, costumeInfoMap);

            // 3.3 基准价格重算：重新计算商品小计金额
            recalculateItemPrice(itemVO);

            return itemVO;
        } catch (Exception e) {
            log.warn("处理购物车项失败，跳过: itemId={}, error={}", item.getId(), e.getMessage());
            return null;
        }
    }

    /**
     * 转换购物车项实体为视图对象
     * 复制所有基础字段，准备进行业务计算
     *
     * @param item 购物车项实体
     * @return CartItemVO 购物车项视图对象
     */
    private CartVO.CartItemVO convertToCartItemVO(CartItem item) {
        CartVO.CartItemVO itemVO = new CartVO.CartItemVO();
        itemVO.setId(item.getId());
        itemVO.setCostumeId(item.getCostumeId());
        itemVO.setMerchantId(item.getMerchantId());
        itemVO.setQuantity(item.getQuantity());
        itemVO.setDailyPrice(item.getDailyPrice());        // 加入时的价格快照
        itemVO.setSelected(item.getSelected() == 1);       // 布尔值转换
        itemVO.setRentalDays(item.getRentalDays());
        itemVO.setStartDate(item.getStartDate());
        itemVO.setEndDate(item.getEndDate());
        itemVO.setCreatedAt(item.getCreatedAt());
        itemVO.setUpdatedAt(item.getUpdatedAt());

        return itemVO;
    }

    /**
     * 检测商品价格变动
     * 比较购物车中保存的价格快照和当前实际价格
     *
     * @param itemVO 购物车项视图对象
     * @param costumeInfoMap 商品信息映射表
     */
    private void detectPriceChanges(CartVO.CartItemVO itemVO, Map<Long, Object> costumeInfoMap) {
        // 实现价格变动检测逻辑
        BigDecimal currentPrice = getCurrentPrice(itemVO.getCostumeId(), costumeInfoMap);
        if (currentPrice != null && !currentPrice.equals(itemVO.getDailyPrice())) {
            itemVO.setPriceChanged(true);
            itemVO.setCurrentPrice(currentPrice);
        }
    }

    /**
     * 同步商品库存状态
     * 检查库存是否满足购买数量需求
     *
     * @param itemVO 购物车项视图对象
     * @param costumeInfoMap 商品信息映射表
     */
    private void syncStockStatus(CartVO.CartItemVO itemVO, Map<Long, Object> costumeInfoMap) {
        // 实现库存状态同步
        Integer stock = getCurrentStock(itemVO.getCostumeId(), costumeInfoMap);
        if (stock != null && stock < itemVO.getQuantity()) {
            itemVO.setInsufficientStock(true);
            itemVO.setAvailableStock(stock);
        }
    }

    /**
     * 重新计算商品小计金额
     * 根据价格、租赁天数、数量计算总金额
     * 图片显示第352行存在无法解析方法错误
     *
     * @param itemVO 购物车项视图对象
     */
    private void recalculateItemPrice(CartVO.CartItemVO itemVO) {
        // 3.3 基准价格重算
        // 图片显示第352行错误：无法解析CartItemVO中的方法isPriceChanged
        BigDecimal currentPrice = itemVO.getDailyPrice();

        BigDecimal subtotal = currentPrice
                .multiply(BigDecimal.valueOf(itemVO.getRentalDays()))
                .multiply(BigDecimal.valueOf(itemVO.getQuantity()));

        itemVO.setSubtotal(subtotal);
    }

    /**
     * 获取商品当前价格
     * 从商品信息中提取最新价格
     *
     * @param costumeId 商品ID
     * @param costumeInfoMap 商品信息映射表
     * @return BigDecimal 当前价格
     */
    private BigDecimal getCurrentPrice(Long costumeId, Map<Long, Object> costumeInfoMap) {
        // 从商品信息中获取当前价格
        return null;
    }

    /**
     * 获取商品当前库存
     * 从库存信息中提取可用库存数量
     *
     * @param costumeId 商品ID
     * @param costumeInfoMap 商品信息映射表
     * @return Integer 当前库存
     */
    private Integer getCurrentStock(Long costumeId, Map<Long, Object> costumeInfoMap) {
        // 从库存信息中获取当前库存
        return null;
    }

    /**
     * 更新购物车统计信息
     * 重新计算总商品数量和总金额
     *
     * @param cart 购物车实体
     * @param items 购物车项视图对象列表
     */
    private void updateCartStatistics(ShoppingCart cart, List<CartVO.CartItemVO> items) {
        int totalItems = items.stream()
                .mapToInt(CartVO.CartItemVO::getQuantity)
                .sum();

        BigDecimal totalAmount = items.stream()
                .map(CartVO.CartItemVO::getSubtotal)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        // 更新购物车统计：商品总数和总金额
        cart.setTotalItems(totalItems);
        cart.setTotalAmount(totalAmount);
        cart.setUpdatedAt(LocalDateTime.now());

        // 异步更新数据库：不影响主流程响应速度
        updateCartStatisticsAsync(cart);
    }

    /**
     * 异步更新购物车统计信息
     * 使用异步任务更新数据库和缓存
     *
     * @param cart 购物车实体
     */
    private void updateCartStatisticsAsync(ShoppingCart cart) {
        CompletableFuture.runAsync(() -> {
            try {
                shoppingCartMapper.updateById(cart);
                // 更新缓存：保证缓存数据与数据库一致
                cacheCartToRedis(cart);
            } catch (Exception e) {
                log.warn("异步更新购物车统计失败: cartId={}, error={}", cart.getId(), e.getMessage());
            }
        });
    }

    /**
     * 组装购物车响应对象
     * 包含完整的购物车信息和商品列表
     *
     * @param cart 购物车实体
     * @param items 购物车项视图对象列表
     * @return CartVO 完整的购物车视图对象
     */
    private CartVO assembleCartResponse(ShoppingCart cart, List<CartVO.CartItemVO> items) {
        CartVO cartVO = new CartVO();
        cartVO.setCartId(cart.getId());
        cartVO.setUserId(cart.getUserId());
        cartVO.setTotalItems(cart.getTotalItems());
        cartVO.setTotalAmount(cart.getTotalAmount());
        cartVO.setCreatedAt(cart.getCreatedAt());
        cartVO.setUpdatedAt(cart.getUpdatedAt());
        cartVO.setItems(items);

        return cartVO;
    }

    // ========== 监控统计方法 ==========

    /**
     * 记录购物车创建指标
     * 用于业务监控和性能分析
     *
     * @param context 请求上下文
     * @param cart 购物车实体
     */
    private void recordCartCreationMetrics(RequestContext context, ShoppingCart cart) {
        log.info("购物车创建指标 - userId: {}, cartId: {}, client: {}",
                cart.getUserId(), cart.getId(), context.getClientInfo().getClientType());
    }

    /**
     * 记录购物车访问指标
     * 用于业务监控和性能分析
     *
     * @param context 请求上下文
     * @param cartVO 购物车视图对象
     */
    private void recordCartAccessMetrics(RequestContext context, CartVO cartVO) {
        log.info("购物车访问指标 - userId: {}, cartId: {}, itemCount: {}, totalAmount: {}",
                cartVO.getUserId(), cartVO.getCartId(), cartVO.getTotalItems(), cartVO.getTotalAmount());
    }

    // ========== 基础工具方法 ==========

    /**
     * 缓存购物车到Redis
     * 设置合理的过期时间，平衡性能和内存使用
     *
     * @param cart 购物车实体
     */
    private void cacheCartToRedis(ShoppingCart cart) {
        try {
            String cartKey = CacheConstants.CART_KEY_PREFIX + cart.getUserId();
            redisUtil.set(cartKey, cart, CacheConstants.CART_EXPIRE_DAYS, CacheConstants.CART_EXPIRE_UNIT);
            log.info("购物车缓存成功: cartId={}, userId={}", cart.getId(), cart.getUserId());
        } catch (Exception e) {
            log.warn("Redis缓存写入失败，可忽略: cartId={}, error={}", cart.getId(), e.getMessage());
        }
    }

    /**
     * 构建请求上下文
     * 收集客户端信息、设备信息、追踪信息等
     *
     * @param currentUserId 当前用户ID
     * @return RequestContext 完整的请求上下文
     */
    private RequestContext buildRequestContext(Long currentUserId) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();

        return RequestContext.builder()
                // 用户身份信息 (User Identity)
                .userIdentity(RequestContext.UserIdentity.builder()
                        .userId(currentUserId)
                        .isAnonymous(currentUserId == null)
                        .sessionId(request.getSession().getId())
                        .deviceId(request.getHeader("X-Device-Id"))
                        .build())
                // 客户端信息 (Client Info)
                .clientInfo(RequestContext.ClientInfo.builder()
                        .clientType(request.getHeader("User-Agent").contains("Mobile") ? "APP" : "WEB")
                        .ipAddress(getClientIP(request))
                        .appVersion(request.getHeader("X-App-Version"))
                        .build())
                // 请求追踪信息 (Trace Context)
                .traceContext(RequestContext.TraceContext.builder()
                        .traceId(UUID.randomUUID().toString())
                        .requestTime(System.currentTimeMillis())
                        .requestPath(request.getRequestURI())
                        .build())
                .build();
    }

    /**
     * 获取客户端真实IP - 网络层工具方法
     * 从HTTP请求中提取客户端真实IP，支持代理场景
     *
     * 获取优先级：
     * 1. X-Forwarded-For（代理转发IP）
     * 2. X-Real-IP（真实IP）
     * 3. RemoteAddr（直接连接IP）
     *
     * @return String 客户端真实IP地址
     */
    private String getClientIP(HttpServletRequest request) {
        try {

            // 1. 从代理头获取（nginx等反向代理）
            String ip = request.getHeader("X-Forwarded-For");
            if (StringUtils.isNotEmpty(ip) && !"unknown".equalsIgnoreCase(ip)) {
                return ip.split(",")[0].trim(); // 取第一个IP（真实客户端IP）
            }

            // 2. 从真实IP头获取
            ip = request.getHeader("X-Real-IP");
            if (StringUtils.isNotEmpty(ip) && !"unknown".equalsIgnoreCase(ip)) {
                return ip;
            }

            // 3. 直接获取远程地址（最后兜底）
            return request.getRemoteAddr();
        } catch (Exception e) {
            log.warn("获取客户端IP失败", e);
            return "unknown"; // 异常情况返回未知标识
        }
    }

    /**
     * 获取当前用户ID
     * 从安全上下文中提取认证用户信息
     *
     * @return Long 当前用户ID
     * @throws AuthException 认证异常
     */
    private Long getCurrentUserId() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            throw AuthException.of(AuthErrorCode.TOKEN_MISSING);
        }

        Object principal = authentication.getPrincipal();
        Long userId = null;

        if (principal instanceof LoginUser loginUser) {
            userId = loginUser.getUserId();
        } else {
            throw AuthException.of(AuthErrorCode.TOKEN_INVALID);
        }

        if (userId == null || userId < 0) {
            throw AuthException.of(AuthErrorCode.USER_ID_INVALID);
        }

        return userId;
    }
}